<#include "license.ftl">
<@license/>
package ${doc.all.package}.service.base;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

import ${doc.all.package}.service.Upgrade;
import ${doc.all.package}.service.ModelViewService;
import redora.service.BusinessRuleViolation;
import redora.configuration.rdo.model.RedoraConfiguration;
import redora.configuration.rdo.service.*;
import redora.exceptions.RedoraException;
import redora.util.JSONWriter;
import redora.util.ResourceFileHandler;

/**
 * @author Redora (www.redora.net)
*/
public class RedoraServletBase extends HttpServlet {
    static final transient Logger l = Logger.getLogger("${doc.all.package}.service.base.RedoraServletBase");

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        JSONWriter writer = new JSONWriter(resp);
        try {
            if ("getFieldsByObjectName".equalsIgnoreCase(req.getParameter("_operationType"))) {
                writer.responseStart();
                ModelViewService.getModelFields(req.getParameter("objectName"), writer);
                writer.responseEnd();
            } else if ("upgradeObjectTable".equalsIgnoreCase(req.getParameter("_operationType"))) {
                Upgrade up = new Upgrade();
                up.upgradeTables(resp.getWriter(), getServletContext());
                up.close();
                writer.responseSuccess();
            } else if ("dropAllTables".equalsIgnoreCase(req.getParameter("_operationType"))) {
                Upgrade up = new Upgrade();
                up.drop(null, true, true);
                up.close();
                writer.responseSuccess();
            } else if ("checkObjectField".equalsIgnoreCase(req.getParameter("_operationType"))) {
                writer.responseStart();
                writer.print("\"");
                Upgrade up = new Upgrade();
                up.check(resp.getWriter());
                up.close();
                writer.print("\"");
                writer.responseEnd();
            } else if ("getObjectCanFindFields".equalsIgnoreCase(req.getParameter("_operationType"))) {
                writer.responseStart();
                ModelViewService.getFindFields(req.getParameter("objectName"), writer);
                writer.responseEnd();
            } else if ("updateRedoraScript".equalsIgnoreCase(req.getParameter("_operationType"))) {
                RedoraConfiguration redoraConfiguration = RedoraConfigurationUtil.from(req);
                RedoraConfigurationService redoraConfigurationService = null;
                try {
                    redoraConfigurationService = ServiceFactory.redoraConfigurationService();
                    Set<BusinessRuleViolation> ret = redoraConfigurationService.persist(redoraConfiguration);
                    if (ret.isEmpty()) {
                        writer.responseStart();
                        RedoraConfigurationUtil.copy(redoraConfiguration, writer);
                        writer.responseEnd();
                    } else {
                        writer.violation(ret);
                    }
                } catch (RedoraException e) {
                    l.log(Level.SEVERE, "Configuration persist error " + redoraConfiguration, e);
                    throw e;
                } finally {
                    ServiceFactory.close(redoraConfigurationService);
                }
            } else if ("getScriptOutput".equalsIgnoreCase(req.getParameter("_operationType"))) {
                Long id = Long.valueOf(req.getParameter("id"));
                RedoraConfigurationServiceJSON redoraConfigurationServiceJSON = null;
                try {
                    redoraConfigurationServiceJSON.fetchLazy(id, writer);
                } catch (RedoraException e) {
                    l.log(Level.SEVERE, "Lazy fetch error for " + id, e);
                    throw e;
                } finally {
                    ServiceFactory.close(redoraConfigurationServiceJSON);
                }
            } else if ("getObjectNames".equalsIgnoreCase(req.getParameter("_operationType"))) {
                writer.responseStart();
                ModelViewService.getModelNames(writer);
                writer.responseEnd();
            } else if ("dropTable".equalsIgnoreCase(req.getParameter("_operationType"))) {
                Upgrade up = new Upgrade();
                up.drop(req.getParameter("objectName"), true, false);
                up.close();
                writer.responseSuccess();
            } else if ("getScriptFileContent".equalsIgnoreCase(req.getParameter("_operationType"))) {
                String scriptName = req.getParameter("scriptName");
                writer.responseStart();
                loadSql(scriptName, resp.getWriter());
                writer.responseEnd();
            } 
            writer.flush();
        } catch (Exception e) {
            l.log(Level.SEVERE, "I failed to process a JSON request: " + req.getQueryString(), e);
            throw new ServletException("I failed to process a JSON request: " + req.getQueryString(), e);
        } 
    }

    void loadSql(String sqlFile, PrintWriter out) throws IOException {
        InputStream in = ResourceFileHandler.findUpgradeFile(sqlFile, getServletContext());
        String sqlSb = IOUtils.toString(in, "UTF-8");
        in.close();
        
        out.print('\"');
        for (String sql : sqlSb.split("(;\\s*\\r\\n)|(;\\s*\\n)")) {
            sql = sql.replaceAll("\r\n", "<br/>");
            sql = sql.replace('\"', '\'');
            if (!sql.equals("")) {
                out.print(sql);
                out.print("<br/>");
            }
        }
        out.print('\"');
    }
}
